//
//  BBLibraryController.m
//  xNose
//
//  Created by ben smith on 9/10/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "BBLibraryController.h"
#import "BBNode.h"
#import "BBLibraryNodeView.h"
#import "BBLibraryView.h"


@implementation BBLibraryController
BBLibraryController* sharedLibraryController;

@synthesize libraryNodes;
@synthesize libView;

+(BBLibraryController*)sharedLibraryController
{
	return sharedLibraryController;
}

+(NSArray*)libraryNodes
{
	return sharedLibraryController.libraryNodes;
}

-(IBAction)loadFromFile:(NSString*)filePath
{
	if (libraryNodes == nil) libraryNodes = [[NSMutableArray alloc] init];
	[libraryNodes addObjectsFromArray:[NSKeyedUnarchiver unarchiveObjectWithFile:filePath]];
}

-(IBAction)saveToFile:(NSString*)filePath
{
	BOOL result = [NSKeyedArchiver archiveRootObject:libraryNodes toFile:filePath];
	
	// TODO: make this nicer
	if (!result)
		[[NSAlert alertWithMessageText:@"Cannot archive Library Node!" defaultButton:@"Oh, ok." alternateButton:nil otherButton:nil informativeTextWithFormat:@"There was an error saving to the file: %@",filePath] runModal];
}

-(void)awakeFromNib
{
	sharedLibraryController = self;
	libraryNodes = [[NSMutableArray alloc] init];
}

-(NSView*)hitTest:(NSPoint)p
{		
	// hit test, but only for certain view types
	// first covnert the point to my view's coordinates
	NSView * hitView = nil;
	if (NSPointInRect(p, [libView frame])) {
		hitView = [libView libHitTest:p];		
	}
	if ([hitView isKindOfClass:[BBLibraryNodeView class]]) return hitView;
	return nil;
}

// remove all the nodes in the library
-(void)clearLibrary
{
	if (libraryNodes == nil) libraryNodes = [[NSMutableArray alloc] init];
	[libraryNodes removeAllObjects];
}

// a very general check to see if a point falls within the library bounds
-(BOOL)pointInLibrary:(NSPoint)p
{
	if (NSPointInRect(p, [libView frame])) return YES;
	return NO;
}

// removes a node from the library
// makes a nice animation
-(void)removeNode:(BBNode*)aNode
{
	if (![libraryNodes containsObject:aNode]) return;
	[libraryNodes removeObject:aNode];
	// dont forget to remove it from the libview as well
	[libView removeNodeView:aNode];
	[libView resetNodeViewPositionsAnimate:YES];
}


// adds a node to the library
// makes a nice animation
-(void)addNode:(BBNode*)aNode
{
	// need to add this node to the library
	// really this means i need to make a copy
	if ([libraryNodes containsObject:aNode]) return;

	// we want to add a copy of the node, not the node itself
	BBNode * nodeCopy = [aNode deepCopy];
	nodeCopy.parent = nil;
	nodeCopy.view = nil;
	nodeCopy.isOpen = NO;
	// we need to clear out all connections
	// this is a hackish way to do this
	[nodeCopy clearConnections];
	for (BBNode* kid in nodeCopy.children) {
		kid.isOpen = NO;
		[kid clearConnections];
		for (BBNode* kidsKid in kid.children) {
			kidsKid.isOpen = NO;
			[kidsKid clearConnections];
		}		
	}
	[libraryNodes addObject:nodeCopy];
	//add to the libview
	[libView addNodeView:nodeCopy animate:YES];
}

// makes the three primitive library nodes
-(void)makeDefaultLibrary
{
	if (libraryNodes == nil) libraryNodes = [[NSMutableArray alloc] init];
	[libraryNodes removeAllObjects];
	
	// add one of each type
	BBNode * container = [BBNode containerNode];
		
	BBNode * leaf  = [BBNode leafNode];
	[libraryNodes addObject:leaf];

	BBNode * collection  = [BBNode collectionNode];
	leaf  = [BBNode leafNode];
	[collection addChild:leaf];
	
	[libraryNodes addObject:collection];
	
	
	container = [BBNode containerNode];
	collection  = [BBNode collectionNode];
	leaf  = [BBNode leafNode];
	
	[container addChild:collection];
	[collection addChild:leaf];
	[libraryNodes addObject:container];
	
	
}
@end
